Expand description
Tao is a cross-platform application window creation and event loop management library.
§Building windows
Before you can build a Window
, you first need to build an EventLoop
. This is done with the
EventLoop::new()
function.
use tao::event_loop::EventLoop;
let event_loop = EventLoop::new();
Once this is done there are two ways to create a Window
:
- Calling
Window::new(&event_loop)
. - Calling
let builder = WindowBuilder::new()
thenbuilder.build(&event_loop)
.
The first method is the simplest, and will give you default values for everything. The second
method allows you to customize the way your Window
will look and behave by modifying the
fields of the WindowBuilder
object before you create the Window
.
§Event handling
Once a Window
has been created, it will generate different events. A Window
object can
generate WindowEvent
s when certain input events occur, such as a cursor moving over the
window or a key getting pressed while the window is focused. Devices can generate
DeviceEvent
s, which contain unfiltered event data that isn’t specific to a certain window.
Some user activity, like mouse movement, can generate both a WindowEvent
and a
DeviceEvent
. You can also create and handle your own custom UserEvent
s, if desired.
You can retrieve events by calling EventLoop::run
. This function will
dispatch events for every Window
that was created with that particular EventLoop
, and
will run until the control_flow
argument given to the closure is set to
ControlFlow
::
ExitWithCode
(which ControlFlow
::
Exit
aliases to), at which
point Event
::
LoopDestroyed
is emitted and the entire program terminates.
Tao no longer uses a EventLoop::poll_events() -> impl Iterator<Event>
-based event loop
model, since that can’t be implemented properly on some platforms (e.g web, iOS) and works poorly on
most other platforms. However, this model can be re-implemented to an extent with
EventLoopExtRunReturn::run_return
. See that method’s documentation for more reasons about why
it’s discouraged, beyond compatibility reasons.
use tao::{
event::{Event, WindowEvent},
event_loop::{ControlFlow, EventLoop},
window::WindowBuilder,
};
let event_loop = EventLoop::new();
let window = WindowBuilder::new().build(&event_loop).unwrap();
event_loop.run(move |event, _, control_flow| {
// ControlFlow::Poll continuously runs the event loop, even if the OS hasn't
// dispatched any events. This is ideal for games and similar applications.
*control_flow = ControlFlow::Poll;
// ControlFlow::Wait pauses the event loop if no events are available to process.
// This is ideal for non-game applications that only update in response to user
// input, and uses significantly less power/CPU time than ControlFlow::Poll.
*control_flow = ControlFlow::Wait;
match event {
Event::WindowEvent {
event: WindowEvent::CloseRequested,
..
} => {
println!("The close button was pressed; stopping");
*control_flow = ControlFlow::Exit
},
Event::MainEventsCleared => {
// Application update code.
// Queue a RedrawRequested event.
//
// You only need to call this if you've determined that you need to redraw, in
// applications which do not always need to. Applications that redraw continuously
// can just render here instead.
window.request_redraw();
},
Event::RedrawRequested(_) => {
// Redraw the application.
//
// It's preferable for applications that do not render continuously to render in
// this event rather than in MainEventsCleared, since rendering in here allows
// the program to gracefully handle redraws requested by the OS.
},
_ => ()
}
});
Event
::
WindowEvent
has a WindowId
member. In multi-window environments, it should be
compared to the value returned by Window::id()
to determine which Window
dispatched the event.
§Drawing on the window
Tao doesn’t directly provide any methods for drawing on a Window
. However it allows you to
retrieve the raw handle of the window and display (see the platform
module and/or the
raw_window_handle
and raw_display_handle
methods), which in turn allows you to create an
OpenGL/Vulkan/DirectX/Metal/etc. context that can be used to render graphics.
Note that many platforms will display garbage data in the window’s client area if the
application doesn’t render anything to the window by the time the desktop compositor is ready to
display the window to the user. If you notice this happening, you should create the window with
visible
set to false
and explicitly make the
window visible only once you’re ready to render into it.
Modules§
- Accelerators describe keyboard shortcuts defined by the application.
- The
Clipboard
struct and associated types. - UI scaling is important, so read the docs for this module if you don’t want to be confused.
- The
Error
struct and associated types. - The
Event
enum and assorted supporting types. - The
EventLoop
struct and assorted supporting types, includingControlFlow
. - UNSTABLE – The
GlobalShortcut
struct and associated types. - UNSTABLE – Types related to the keyboard.
- UNSTABLE – The
Menu
struct and associated types. - Types useful for interacting with a user’s monitors.
- Contains traits with platform-specific methods in them.
- UNSTABLE – The
SystemTray
struct and associated types. - The
Window
struct and associated types.
Structs§
- Whenever you receive an event arising from a particular tray, this event contains a
TrayId
which identifies its origin.